package com.theme.passport.controller.app;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.theme.common.base.StringHandler;
import com.theme.common.frame.exception.ErrorCode;
import com.theme.common.mvc.utils.RedisKeys;
import com.theme.common.mvc.view.R;
import com.theme.common.third.sms.AliyunSmsHandler;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("app/sms/aliyun")
@CrossOrigin
@Api("阿里云发送短信")
public class AliyunSmsController {

    private static final Logger logger = LoggerFactory.getLogger(AliyunSmsController.class);

    @Value("${sms.aliyun.code}")
    private String smsAliyunCode ;
    @Resource(name = "redisTemplate")
    private ValueOperations<String, String> redisCache;

    @GetMapping("/sendCode")
    @ApiOperation("发送短信验证码")
    public R sendCode(String moblie) throws ClientException {
        // 校验验证码发送次数
        R r = validatorCodeCount(moblie);
        if (!R.isOk(r)){
            return r;
        }

        String code = random4();//验证码 6位数
        String loginKey = RedisKeys.SEND_CODE.concat(moblie);
        redisCache.set(loginKey,code,5, TimeUnit.MINUTES); //存储时间 30 分钟

        logger.info("手机号: {},你的验证码为code:[{}]", moblie,code);
        SendSmsResponse sendSmsResponse = AliyunSmsHandler.sendVerifyCode(moblie, code, smsAliyunCode);
        String response = sendSmsResponse.getCode();
        if(!response.equals("OK")){
            return R.error(ErrorCode.SEND_MESSAGE_ERROR.getCode(),ErrorCode.SEND_MESSAGE_ERROR.getMsg());
        }
        String sendCodeCount = RedisKeys.SEND_COUNT.concat(moblie);
        String result = redisCache.get(sendCodeCount);
        if (StringHandler.isEmpty(result)){
            redisCache.set(sendCodeCount,"0",12, TimeUnit.HOURS); //存储时间 12 小时
        }
        redisCache.increment(sendCodeCount);
        return R.ok().put("data",sendSmsResponse);
    }

    @GetMapping("/sendCodeTest")
    @ApiOperation("发送短信验证码")
    public R sendCodeTest(String moblie) {
        if(StringHandler.isEmpty(moblie)){
            return R.error(ErrorCode.REGISTER_USER_PHONE_MISSING.getCode(),ErrorCode.REGISTER_USER_PHONE_MISSING.getMsg());
        }
        // 校验验证码发送次数
        R r = validatorCodeCount(moblie);
        if (!R.isOk(r)){
            return r;
        }

        String s = random4();//验证码 6位数
        String loginKey = RedisKeys.SEND_CODE.concat(moblie);
        redisCache.set(loginKey,s,5, TimeUnit.MINUTES); //存储时间 30 分钟

        logger.info("手机号: {},你的验证码为code:[{}]", moblie,s);
        String code = "OK";
        if(!code.equals("OK")){
            return R.error(ErrorCode.SEND_MESSAGE_ERROR.getCode(),ErrorCode.SEND_MESSAGE_ERROR.getMsg());
        }
        String sendCodeCount = RedisKeys.SEND_COUNT.concat(moblie);
        String result = redisCache.get(sendCodeCount);
        if (StringHandler.isEmpty(result)){
            redisCache.set(sendCodeCount,"0",12, TimeUnit.HOURS); //存储时间 12 小时
        }
        redisCache.increment(sendCodeCount);
        return R.ok(s);
    }


    private R validatorCodeCount(String moblie) {
        String sendCodeCount = RedisKeys.SEND_COUNT.concat(moblie);
        String result = redisCache.get(sendCodeCount);
        if (StringHandler.isEmpty(result)){
            return R.ok();
        }
        Integer count = Integer.valueOf(result);
        if (count <= 24){
            return R.ok();
        }
        return R.error(ErrorCode.REGISTER_USER_PHONE_MAX_COUNT_ERROR.getCode(),ErrorCode.REGISTER_USER_PHONE_MAX_COUNT_ERROR.getMsg());
    }


    private static String random4() {
        return String.valueOf(ThreadLocalRandom.current().nextInt(1000, 10000));
    }

    private static String random6() {
        return String.valueOf(ThreadLocalRandom.current().nextInt(100000, 1000000));
    }

}